<?php
/**
 * Smarty plugin
 * @package Smarty
 * @subpackage plugins
 */


/**
 * Smarty truncate modifier plugin
 *
 * Type:     modifier<br>
 * Name:     truncate<br>
 * Purpose:  Truncate a string to a certain length if necessary,
 *           optionally splitting in the middle of a word, and
 *           appending the $etc string or inserting $etc into the middle.
 * @link http://smarty.php.net/manual/en/language.modifier.truncate.php
 *          truncate (Smarty online manual)
 * @author   Monte Ohrt <monte at ohrt dot com>
 * @param string
 * @param integer
 * @param string
 * @param boolean
 * @param boolean
 * @return string
 */

function smarty_modifier_truncate($string, $plength, $charset = 'utf-8') {
    $dot = '...';
    $plength = (int)$plength;
    $strcut= '';
    $strlen= strlen($string);
    if($charset == 'utf-8'){
        $n = $tn = $tnl = $noc = 0;
        while($n < $strlen) {
            $t = ord($string[$n]);
            $tnl = $tn;
            if($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) {
                $tn = 1; $n++; $noc++;
            } elseif(194 <= $t && $t <= 223) {
                $tn = 2; $n += 2; $noc += 2;
            } elseif(224 <= $t && $t < 239) {
                $tn = 3; $n += 3; $noc += 2;
            } elseif(240 <= $t && $t <= 247) {
                $tn = 4; $n += 4; $noc += 2;
            } elseif(248 <= $t && $t <= 251) {
                $tn = 5; $n += 5; $noc += 2;
            } elseif($t == 252 || $t == 253) {
                $tn = 6; $n += 6; $noc += 2;
            } else {
                $n++;
            }
            if($noc >= $plength) {
                break;
            }
        }
        if($noc > $plength) {
            $n -= $tn;
            $tn = $tnl;
        }
        if($strlen>$n){
            return substr($string, 0, $n-$tn).$dot;
        }else{
            return substr($string, 0, $n);
        }
    }else{
        if($strlen <= $plength+strlen($dot)) {
            return $string;
        }
        for($i = 0; $i < $plength; $i++) {
            $strcut .= ord($string[$i]) > 127 ? $string[$i].$string[++$i] : $string[$i];
        }
        return $strcut.$dot;
    }
}

/* vim: set expandtab: */

?>
